﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Web;
//using System.Data;
//using System.IO;
//using System.Reflection;
//using System.Collections;
//using System.Text;

//namespace Citi.Helpers
//{
//    public class ChildrenInformation
//    {
//        public string Name { get; set; }
//        public IList Items { get; set; }
//    }

//    public class ImportHelper
//    {
//        public List<ChildrenInformation> Children = new List<ChildrenInformation>();

//        #region Generic Import

//        public DataTable ConvertTxtToDataTable(string filePath, char separator)
//        {
//            var streamReader = new StreamReader(filePath);
//            var header = streamReader.ReadLine();
//            var dataTable = new DataTable();

//            var columns = header.Split(separator).ToList();

//            foreach (var column in columns)
//            {
//                if (dataTable.Columns.Cast<DataColumn>().Any(x => x.ColumnName == column))
//                    dataTable.Columns.Add(new DataColumn(string.Concat(column, columns.IndexOf(column))));
//                else
//                    dataTable.Columns.Add(new DataColumn(column));
//            }

//            var line = streamReader.ReadLine();

//            while (line != null)
//            {
//                var dataRow = dataTable.NewRow();
//                var columnValues = line.Split(separator);

//                for (int col = 0; col < columnValues.Count() - 1; col++)
//                    dataRow[col] = columnValues[col];

//                dataTable.Rows.Add(dataRow);
//                line = streamReader.ReadLine();
//            }

//            return dataTable;
//        }

//        private List<T> ImportFileTxt<T>(ColumnMapping mappingColumn, string pathFile, string fileDescription, ref List<ErrorModel> errors, char separator, bool updateReferenceDate = false) where T : EntityBase
//        {
//            DateTime pathDate;
//            if (ValidateFile(pathFile, fileDescription, errors, out pathDate)) return null;

//            return ImportDataTable<T>(mappingColumn, fileDescription, errors, updateReferenceDate, pathDate, ConvertTxtToDataTable(pathFile, separator));
//        }

//        private List<T> ImportFile<T>(ColumnMapping mappingColumn, string pathFile, string fileDescription, ref List<ErrorModel> errors, string worksheetName = null, bool updateReferenceDate = false) where T : EntityBase
//        {
//            DateTime pathDate;
//            if (ValidateFile(pathFile, fileDescription, errors, out pathDate)) return null;

//            using (var reader = new ExcelReader(pathFile, true, true))
//            {
//                var dataTable = worksheetName == null ? reader.GetData() : reader.GetData(worksheetName);
//                return ImportDataTable<T>(mappingColumn, fileDescription, errors, updateReferenceDate, pathDate, dataTable);
//            }
//        }

//        private List<T> ImportDataTable<T>(ColumnMapping mappingColumn, string fileDescription, List<ErrorModel> errors, bool updateReferenceDate, DateTime pathDate, DataTable dataTable) where T : EntityBase
//        {
//            var rows = dataTable.Rows.Cast<DataRow>().ToList();
//            var lines = new List<T>();
//            var blankLine = 0;

//            foreach (var row in rows)
//            {
//                if (row.ItemArray.Count(x => string.IsNullOrEmpty(x.ToString())) == row.ItemArray.Count())
//                {
//                    blankLine++;
//                    if (blankLine >= 5) break;
//                    continue;
//                }

//                var line = rows.IndexOf(row);

//                ErrorModel error;

//                var objectLine = AddLine<T>(mappingColumn, row, pathDate, out error);

//                if (objectLine == null)
//                {
//                    error.Line = line;
//                    error.File = fileDescription;
//                    errors.Add(error);
//                    continue;
//                }

//                if (updateReferenceDate)
//                {
//                    var property = GetPropertyCodeOrDescription(objectLine.GetType());
//                    var databaseObject = GetItemFromChildren(property.GetValue(objectLine, null).ToString(), objectLine.GetType());

//                    if (databaseObject != null)
//                    {
//                        if (databaseObject.IsSameInformation(objectLine)) continue;

//                        objectLine.UpdateDates(pathDate);
//                        lines.Add(objectLine);
//                    }
//                    else
//                        lines.Add(objectLine);
//                }
//                else
//                    lines.Add(objectLine);
//            }
//            return lines;
//        }

//        private static bool ValidateFile(string pathFile, string fileDescription, List<ErrorModel> errors, out DateTime pathDate)
//        {
//            pathDate = DateTime.MinValue;

//            if (!File.Exists(pathFile))
//            {
//                errors.Add(new ErrorModel(0, string.Format(Message.FileNotExists, pathFile), fileDescription));
//                return true;
//            }

//            pathDate = GetDateFile(pathFile);

//            if (pathDate == DateTime.MinValue)
//            {
//                errors.Add(new ErrorModel(0, string.Format(Message.InvalidFileName, fileDescription, pathFile), fileDescription));
//                return true;
//            }

//            return false;
//        }

//        private T AddLine<T>(ColumnMapping mappingColumn, DataRow row, DateTime pathDate, out ErrorModel errorModel) where T : EntityBase
//        {
//            errorModel = new ErrorModel();

//            var objectLine = (T)Activator.CreateInstance(typeof(T));

//            try
//            {
//                foreach (PropertyInfo propertyInfo in mappingColumn.GetType().GetProperties())
//                {
//                    var columnIndex = int.Parse(propertyInfo.GetValue(mappingColumn, null).ToString());

//                    if (columnIndex == -1) continue;

//                    var value = row[columnIndex].ToString();

//                    if (string.IsNullOrEmpty(value)) continue;

//                    var objectProperty = objectLine.GetType().GetProperty(propertyInfo.Name);
//                    if (objectProperty == null) continue;

//                    if (objectProperty.PropertyType.Namespace.StartsWith("Citi.HeadCount.Domain"))
//                    {
//                        var child = GetDomainValue(value, objectProperty, row, mappingColumn, pathDate);
//                        objectProperty.SetValue(objectLine, child, null);
//                    }
//                    else
//                    {
//                        if (objectProperty.PropertyType.IsGenericType && objectProperty.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
//                        {
//                            objectProperty.SetValue(objectLine,
//                                string.IsNullOrEmpty(value)
//                                    ? null
//                                    : Convert.ChangeType(value, objectProperty.PropertyType.GetGenericArguments()[0]), null);
//                        }
//                        else
//                        {
//                            if (!(string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value)))
//                                objectProperty.SetValue(objectLine, Convert.ChangeType(value, objectProperty.PropertyType), null);
//                            else if (!IsNumericType(objectProperty.PropertyType))
//                                objectProperty.SetValue(objectLine, Convert.ChangeType(value, objectProperty.PropertyType), null);
//                        }
//                    }
//                }

//                FillDate("ReferenceDate", objectLine, pathDate);
//                FillDate("LastUpdate", objectLine, DateTime.Now);

//                return objectLine;
//            }
//            catch (Exception e)
//            {
//                errorModel = new ErrorModel(0, e.Message, string.Empty);
//                return default(T);
//            }
//        }

//        private object GetDomainValue(string value, PropertyInfo objectProperty, DataRow row, ColumnMapping mappingColumn, DateTime pathDate)
//        {
//            var child = GetItemFromChildren(value, objectProperty.PropertyType);

//            if (child == null)
//            {
//                child = (EntityBase)Activator.CreateInstance(objectProperty.PropertyType);

//                FillProperty("Code", objectProperty, row, mappingColumn, child);
//                FillProperty("Description", objectProperty, row, mappingColumn, child);
//                FillDate("ReferenceDate", child, pathDate);
//            }

//            return child;
//        }

//        private EntityBase GetItemFromChildren(string value, Type objectProperty)
//        {
//            var childrenInformation = Children.FirstOrDefault(x => x.Name == objectProperty.Name);

//            if (childrenInformation == null)
//            {
//                var repositoryBaseType = typeof(Citi.HeadCount.Domain.Repository.RepositoryBase<>);
//                Type[] typeArgs = { objectProperty };
//                var genericType = repositoryBaseType.MakeGenericType(typeArgs);
//                var repository = Activator.CreateInstance(genericType);

//                childrenInformation = new ChildrenInformation
//                {
//                    Name = objectProperty.Name,
//                    Items = ((IList)repository.GetType().GetMethod("GetAllDistinctByCodeOrDescription").Invoke(repository, null))
//                };
//                Children.Add(childrenInformation);
//            }

//            var propertyKey = objectProperty.GetProperty("Code");
//            var child = propertyKey != null ? childrenInformation.Items.Cast<EntityBase>().FirstOrDefault(x => x != null && propertyKey.GetValue(x, null).ToString() == value) : null;

//            if (child == null)
//            {
//                propertyKey = objectProperty.GetProperty("Description");
//                child = propertyKey != null ? childrenInformation.Items.Cast<EntityBase>().FirstOrDefault(x => x != null && propertyKey.GetValue(x, null).ToString() == value) : null;
//            }
//            return child;
//        }

//        private static void FillDate(string propertyName, object child, DateTime date)
//        {
//            var propertyKey = child.GetType().GetProperty(propertyName);
//            if (propertyKey == null) return;

//            propertyKey.SetValue(child, date, null);
//        }

//        private static void FillProperty(string propertyName, PropertyInfo objectProperty, DataRow row, ColumnMapping mappingColumn, object child)
//        {
//            var propertyKey = objectProperty.PropertyType.GetProperty(propertyName);
//            if (propertyKey == null) return;

//            var propertyInfo = mappingColumn.GetType().GetProperty(string.Concat(objectProperty.PropertyType.Name, propertyName));
//            if (propertyInfo == null) return;

//            var columnIndex = int.Parse(propertyInfo.GetValue(mappingColumn, null).ToString());
//            if (columnIndex > -1)
//                propertyKey.SetValue(child, Convert.ChangeType(row[columnIndex], propertyKey.PropertyType), null);
//        }

//        private static PropertyInfo GetPropertyCodeOrDescription(Type objectProperty)
//        {
//            var propertyKey = objectProperty.GetProperty("Code");
//            if (propertyKey == null)
//                propertyKey = objectProperty.GetProperty("Description");
//            return propertyKey;
//        }

//        private static DateTime GetDateFile(string pathFile)
//        {
//            var pathWithExtension = pathFile.Replace(".xlsx", string.Empty).Replace(".xls", string.Empty);

//            try
//            {
//                var date = pathWithExtension.Split(new[] { '_' }).Last();
//                return new DateTime(int.Parse(date.Substring(0, 4)), int.Parse(date.Substring(4, 2)), 1);
//            }
//            catch (Exception)
//            {
//                return DateTime.MinValue;
//            }
//        }

//        #endregion

//        public bool IsNumericType(Type type)
//        {
//            switch (Type.GetTypeCode(type))
//            {
//                case TypeCode.Byte:
//                case TypeCode.SByte:
//                case TypeCode.UInt16:
//                case TypeCode.UInt32:
//                case TypeCode.UInt64:
//                case TypeCode.Int16:
//                case TypeCode.Int32:
//                case TypeCode.Int64:
//                case TypeCode.Decimal:
//                case TypeCode.Double:
//                case TypeCode.Single:
//                    return true;
//                default:
//                    return false;
//            }
//        }
//    }
//}

